package com.nutiteq.storedmaps;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Vector;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.ItemCommandListener;
import javax.microedition.lcdui.StringItem;
import javax.microedition.midlet.MIDletStateChangeException;

import com.nutiteq.MapComponent;
import com.nutiteq.components.WgsPoint;
import com.nutiteq.controls.ControlKeys;
import com.nutiteq.controls.MGMapsKeysHandler;
import com.nutiteq.fs.FileSystem;
import com.nutiteq.fs.JSR75FileSystem;
import com.nutiteq.helpers.FileBrowser;
import com.nutiteq.helpers.FileBrowserListener;
import com.nutiteq.listeners.MapListener;
import com.nutiteq.maps.StoredMap;
import com.nutiteq.utils.InitializedCanvas;
import com.nutiteq.utils.LogForm;

public class MapCanvas extends Canvas implements CommandListener, ItemCommandListener, MapListener,
    InitializedCanvas, FileBrowserListener {
  MapCanvas instance;

  private Image splash;

  private final Timer timer;
  Thread starter;

  private final MapComponent mapComponent;

  private final Command exit;
  private final Command browse;

  private Form storedForm;
  private StringItem storedButton;
  private final FileBrowser fb;
  private final FileSystem fs;

  private boolean initialized;

  private boolean initialCenter;

  public MapCanvas() {
    instance = this;

    try {
      splash = Image.createImage("/splash.png");
    } catch (final IOException e) {
      e.printStackTrace();
    }

    timer = new Timer();
    timer.schedule(new TimerTask() {
      public void run() {
        initialize();
      }
    }, 3000);
    mapComponent = new MapComponent("abcdtrial", StoredMapSample.instance, getWidth(), getHeight(),
        new WgsPoint(0, 0), 1);

    exit = new Command("Exit", Command.EXIT, 0);
    browse = new Command("Browse", Command.ITEM, 0);

    fs = new JSR75FileSystem();

    mapComponent.setFileSystem(fs);

    fb = new FileBrowser(fs);
  }

  public void initialize() {
    // show path form
    storedButton = new StringItem("Browse...", "", Item.BUTTON);
    storedButton.setDefaultCommand(browse);
    storedButton.setItemCommandListener(this);

    storedForm = new Form("Stored Maps");
    storedForm.append(storedButton);
    storedForm.addCommand(exit);
    storedForm.setCommandListener(this);

    Display.getDisplay(StoredMapSample.instance).setCurrent(storedForm);
  }

  public void startMap() {
    mapComponent.startMapping();
    if (hasPointerEvents()) {
      mapComponent.showDefaultOnScreenZoomControls();
    } else {
      mapComponent.showDefaultCursor();
    }

    mapComponent.setControlKeysHandler(new MGMapsKeysHandler());
    mapComponent.showZoomLevelIndicator(true);

    mapComponent.setMapListener(this);

    addCommand(exit);
    addCommand(LogForm.SHOW_LOG);
    setCommandListener(this);
    initialized = true;
    repaint();
  }

  protected void paint(final Graphics g) {
    if (!initialized) {
      //paint splash
      g.setColor(0xFFFFFFFF);
      g.setClip(0, 0, getWidth(), getHeight());
      g.fillRect(0, 0, getWidth(), getHeight());
      g.drawImage(splash, (getWidth() - splash.getWidth()) / 2,
          (getHeight() - splash.getHeight()) / 2, Graphics.TOP | Graphics.LEFT);
      return;
    }

    g.setClip(0, 0, getWidth(), getHeight());
    mapComponent.paint(g);
  }

  protected void keyPressed(final int keyCode) {
    if (!initialized) {
      return;
    }
    mapComponent.keyPressed(keyCode);
  }

  protected void keyReleased(final int keyCode) {
    if (!initialized) {
      return;
    }
    mapComponent.keyReleased(keyCode);
  }

  protected void keyRepeated(final int keyCode) {
    if (!initialized) {
      return;
    }
    mapComponent.keyRepeated(keyCode);
  }

  protected void pointerDragged(final int x, final int y) {
    if (!initialized) {
      return;
    }
    mapComponent.pointerDragged(x, y);
  }

  protected void pointerPressed(final int x, final int y) {
    if (!initialized) {
      return;
    }
    mapComponent.pointerPressed(x, y);
  }

  protected void pointerReleased(final int x, final int y) {
    if (!initialized) {
      return;
    }
    mapComponent.pointerReleased(x, y);
  }

  public void commandAction(final Command cmd, final Displayable d) {
    if (cmd == exit) {
      if (initialized) {
        mapComponent.stopMapping();
      }
      try {
        StoredMapSample.instance.destroyApp(true);
      } catch (final MIDletStateChangeException ignore) {
      }
    } else if (cmd == LogForm.SHOW_LOG) {
      Display.getDisplay(StoredMapSample.instance).setCurrent(
          new LogForm(mapComponent, StoredMapSample.instance, this));
    }
  }

  public void mapClicked(final WgsPoint p) {

  }

  public void mapMoved() {

  }

  public void needRepaint(final boolean mapIsComplete) {
    repaint();
    if(mapIsComplete && !initialCenter){
      mapComponent.setMiddlePoint(((StoredMap)mapComponent.getMap()).getCenterLocation(), ((StoredMap)mapComponent.getMap()).getCenterZoom());
      initialCenter=true;
    }
  }

  public void commandAction(final Command cmd, final Item item) {
    // browse
    if (cmd == browse) {
      fb.showUI(StoredMapSample.instance, null, this);
    }
  }

  public void browsingCancelled() {
    Display.getDisplay(StoredMapSample.instance).setCurrent(storedForm);
  }

  public boolean directoryListed(final String currentDir, final Vector files) {
    // check if the current directory contains a file named "something_1"
    boolean foundCacheConf = false;
    String foundMapType = null;

    final int len = files.size();
    for (int i = 0; i < len; i++) {
      String file = (String) files.elementAt(i);

      // check if the file is cache.conf
      if (file.equals("cache.conf")) {
        foundCacheConf = true;
        continue;
      }

      // if already found map type, continue
      if (foundMapType != null) {
        continue;
      }

      if (file.endsWith("/")) {
        file = file.substring(0, file.length() - 1);
      }

      // check if the file has the structure maptype_number 
      final int ind = file.indexOf('_');
      if (ind < 0) {
        continue;
      }

      int value = -1;
      try {
        value = Integer.parseInt(file.substring(ind + 1));
      } catch (final Exception ex) {
      }

      if (value < 0 || value >= 32) {
        continue;
      }

      // found map
      foundMapType = file.substring(0, ind);
    }

    // nothing found, return null
    if (!foundCacheConf || foundMapType == null) {
      return false;
    }

    final StoredMap sm = new StoredMap(foundMapType, currentDir, true);
    final Image missing = Image.createImage(sm.getTileSize(), sm.getTileSize());
    final Graphics graphics = missing.getGraphics();
    graphics.setColor(0xFFCCCECC);
    graphics.fillRect(0, 0, sm.getTileSize(), sm.getTileSize());
    sm.setMissingTileImage(missing);
    mapComponent.setMap(sm);

    // set disp
    Display.getDisplay(StoredMapSample.instance).setCurrent(this);

    // start mapping
    startMap();

    return true;
  }

  public boolean fileSelected(final String currentDir, final String filename) {
    // not used
    return false;
  }
}
